﻿/*
crear el esquema de la venta donde se muestra
el producto que se vende
la cantidad que se va vender
se debe indicar si se esta agotando
se debe descontar de existencias la cantidad
se debe de incrementar el monto en cajas
y quien hizo la venta
*/
--funcion para reservar un id de venta parametros(id_sucursal,id_empleado)
create or replace function reserva_venta(integer,integer) returns integer as
$$
declare
idsucursal alias for $1;
idempleado alias for $2;
idventa int;
begin
insert into ventas(fecha,subtotal,total,id_sucursal,id_empleado)values(now(),'0','0',idsucursal,idempleado);
select into idventa id_venta from ventas order by id_venta desc limit 1;
return idventa;
end;
$$ Language 'plpgsql';
select  s.id_producto from  productos_servicios p join productoxsucursal s on s.id_producto=p.id_producto where p.id_producto=idprod and s.id_sucursal=idsucursal
--funcion para revisar y decrementar existencia parametros (id_venta,id_producto,cantdad)
--el producto debe existir en la sucursal
create or replace function agregar_producto(integer,integer,integer) returns text as 
$$
declare
idventa alias for $1;
idprod	alias for $2;
_cantidad alias for $3;
exist int;
idsucursal int;
resultado text;
existe int;
verprod int;
cant_ant int;
begin
	select into idsucursal id_sucursal from ventas where id_venta=idventa;
	IF NOT FOUND THEN
		RAISE EXCEPTION 'No se encontro la venta % en la sucursal ',idventa;
	END IF;
	select into existe s.id_producto from  productos_servicios p join productoxsucursal s on s.id_producto=p.id_producto 
	where p.id_producto=idprod and s.id_sucursal=idsucursal;
	IF NOT FOUND THEN
		RAISE EXCEPTION 'No se encontro el producto % en la sucursal % ',idprod,idsucursal;
	END IF;
	select into exist existencia from productoxsucursal where id_producto=idprod;
	if(exist=0)then
	resultado:='No hay producto en existencia';
		else
			if(_cantidad>exist)then
				resultado:='No hay existencias suficientes, solo hay '||exist||' disponibles';
			else
			update productoxsucursal set existencia=(select existencia from productoxsucursal where id_producto=idprod)-_cantidad where id_producto=idprod;
			
			select into verprod id_producto from productoxventa where id_producto=idprod and id_venta=idventa;
			IF NOT FOUND THEN
			insert into productoxventa(id_venta,id_producto,cantidad)values(idventa,idprod,_cantidad);
			resultado:='Se ha hecho la operacion correctamente';
			else 
			select into cant_ant cantidad from productoxventa where id_producto=idprod and id_venta=idventa;
			update productoxventa set cantidad=_cantidad+cant_ant where id_producto=idprod and id_venta=idventa;
			resultado:='Se han agregado '||_cantidad||' productos';
				END IF;
						
			end if;
			if(exist<10 and exist!=0)then
			resultado:='La existencia del producto '||idprod||' se esta agotando';
			--inert into productoxcompra(id_compra,id_producto,cantidad)values(?,idprod,50);
		end if;
	end if;
	
	return resultado;
end;
$$ Language 'plpgsql';
--funcion para eliminar de la venta e incrementar existencia parametros(id_venta,id_producto,cantidad)
create or replace function quitar_producto(integer,integer) returns text as $$
declare
idventa 	alias for $1;
idprod	 	alias for $2;
exist int;
idsucursal int;
resultado text;
existe int;
cant int;
begin
	select into existe id_producto from  productoxventa where id_producto=idprod and id_venta=idventa;
	IF NOT FOUND THEN
		RAISE EXCEPTION 'No se encontro el producto % en la venta % ',idprod,idventa;
	END IF;
	select into idsucursal id_sucursal from ventas where id_venta=idventa;
	select into exist existencia from productoxsucursal where id_producto=idprod;
	select into cant cantidad from productoxventa  where id_producto=idprod and id_venta=idventa;
			update productoxsucursal set existencia=(select existencia from productoxsucursal where id_producto=idprod)+cant where id_producto=idprod;
			delete from productoxventa where id_producto=idprod and id_venta=idventa;
			resultado:='Se ha hecho la operacion correctamente';
		
	return resultado;
end;
$$ language'plpgsql';
--funcion para actualizar de la venta y decrementar o incrementar existencia dependiendo del caso parametros(id_venta,id_producto,cantidad actual,nueva cantidad)
create or replace function actualizar_producto(integer,integer,integer) returns text as $$
declare
idventa 	alias for $1;
idprod	 	alias for $2;
cant_nueva	alias for $3;
exist int;
idsucursal int;
resultado text;
existe int;
cant_ant int;
begin
	select into existe id_producto from  productoxventa where id_producto=idprod and id_venta=idventa;
	IF NOT FOUND THEN
		RAISE EXCEPTION 'No se encontro el producto % en la venta %',idprod,idventa;
	END IF;
	select into idsucursal id_sucursal from ventas where id_venta=idventa;
	select into exist existencia from productoxsucursal where id_producto=idprod;
	select into cant_ant cantidad from productoxventa where id_producto=idprod and id_venta=idventa;
			if(cant_nueva<cant_ant)then
			update productoxsucursal set existencia=(select existencia from productoxsucursal where id_producto=idprod)+(cant_ant-cant_nueva) where id_producto=idprod;
			elsif(cant_nueva>cant_ant)then
			update productoxsucursal set existencia=(select existencia from productoxsucursal where id_producto=idprod)-(cant_nueva-cant_ant) where id_producto=idprod;
			end if;
			update productoxventa set cantidad=cant_nueva where id_producto=idprod and id_venta=idventa;
			resultado:='Se ha hecho la operacion correctamente';
	return resultado;
end;
$$ language'plpgsql';
--trigger para contar o descontar del subtotal de la venta de acuerdo al caso
create trigger cargos after insert or delete or update on productoxventa
for each row execute procedure generar_cargos();
--drop trigger cargos on productoxventa

--funcion para el trigger
create or replace function generar_cargos() returns trigger as
$$
declare
sub		money;
monto 		money;
begin

	if(TG_OP='INSERT')then
		select into monto precio_venta from  productos_servicios where id_producto=new.id_producto;
		select into sub subtotal from ventas where id_venta=new.id_venta;
		monto:=monto*new.cantidad;
		sub:=monto+sub;
		update ventas set subtotal=sub where id_venta=new.id_venta;
		return new;
	elsif(TG_OP = 'UPDATE')then
		select into monto precio_venta from  productos_servicios where id_producto=new.id_producto;
		select into sub subtotal from ventas where id_venta=new.id_venta;
		if(new.cantidad<old.cantidad)then
		monto:=monto*(old.cantidad-new.cantidad);
		sub:=sub-monto;
		elsif(new.cantidad>old.cantidad)then
		monto:=monto*(new.cantidad-old.cantidad);
		sub:=sub+monto;
		end if;
		update ventas set subtotal=sub where id_venta=new.id_venta;
		return new;
	elsif(TG_OP='DELETE')then
		select into monto precio_venta from  productos_servicios where id_producto=old.id_producto;
		select into sub subtotal from ventas where id_venta=old.id_venta;
		monto:=monto*old.cantidad;
		sub:=sub-monto;
		update ventas set subtotal=sub where id_venta=old.id_venta;
		return old;
	end if;
	
	return null;
end;
$$ language'plpgsql';
--funcion para generar el total
create or replace function cerrar_venta(integer)returns text as $$
declare
idventa 	alias for $1;
_total 		money;
_subtotal	money;
iva		float:=0.16;
existe		int;
cargos		money;
resultado	text;
begin
	select into existe id_venta from ventas where id_venta=idventa;
	IF NOT FOUND THEN
		RAISE EXCEPTION 'No exsite la venta % ',idventa;
	END IF;
	select into _subtotal subtotal from ventas where id_venta=idventa;
	cargos=(_subtotal*iva);
	_total=cargos+_subtotal;
	update ventas set total=_total where id_venta=idventa;
	resultado:='cargos x iva: '||cargos||' generando un total de: '||_total;
	return resultado;
end;
$$ language'plpgsql';
--se reserva el id de la venta para la sucursal y el empleado
select reserva_venta(1,1);
--saber que venta va(no necesario el valor esta arriba) 
select  id_venta from ventas order by id_venta desc limit 1;
--se agregan los productos a la venta (id_venta,id_producto,cantdad)
select agregar_producto(12,1,5);
select agregar_producto(11,3,2);
select agregar_producto(11,2,3);
select agregar_producto(11,1,5);
--si se quieren quitar productos de la venta (id_venta,id_producto)
select quitar_producto(11,1);
select quitar_producto(11,2);
select quitar_producto(11,1);
--Actualizar producto de la venta (id_venta,id_producto,nueva cantidad)
select actualizar_producto(11,1,1); 
select actualizar_producto(11,2,1); 
select actualizar_producto(11,1,3);
--cerrar la venta generando el total (id_venta)
select cerrar_venta(11);

select * from productoxsucursal order by id_producto asc;
select * from productoxventa where id_venta=11
select * from ventas where id_venta=12
select * from productos_servicios